/*---------------------------------------------------------------------------

  file_io.c

  This file contains routines for doing direct input/output, file-related
  sorts of things.	Most of the system-specific code for unzip is contained
  here, including the non-echoing password code for decryption (bottom).

  Modified: 24 Jun 92 - HAJK
  Fix VMS support
  ---------------------------------------------------------------------------*/


#include <stdio.h>
#include "memfile.h"
#include "zunzip.h"

#if 0
/****************************/
/* Function FillBitBuffer() */
/****************************/

int FillBitBuffer()
{
	/*
	 * Fill bitbuf, which is 32 bits.  This function is only used by the
	 * READBIT and PEEKBIT macros (which are used by all of the uncompression
	 * routines).
	 */
	UWORD temp;

	zipeof = 1;
	while (bits_left < 25 && ReadByte(&temp) == 8)
	{
	  bitbuf |= (ULONG)temp << bits_left;
	  bits_left += 8;
	  zipeof = 0;
	}
	return 0;
}

/***********************/
/* Function ReadByte() */
/***********************/

int ReadByte(x)
UWORD *x;
{
	/*
	 * read a byte; return 8 if byte available, 0 if not
	 */


	if (csize-- <= 0)
		return 0;

	if (incnt == 0) {
		if ((incnt = read(zipfd, (char *) inbuf, INBUFSIZ)) <= 0)
			return 0;
		/* buffer ALWAYS starts on a block boundary:  */
		inptr = inbuf;
	}
	*x = *inptr++;
	--incnt;
	return 8;
}

#else
/*
 * This function is used only by the NEEDBYTE macro in inflate.c.
 * It fills the buffer and resets the count and pointers for the
 * macro to resume processing.	The count is set to the number of bytes
 * read in minus one, while the pointer is set to the beginning of the
 * buffer.	This is all to make the macro more efficient.
 *
 * In exceptional circumstances, zinflate can read a byte or two past the
 * end of input, so we allow this for a little bit before returning
 * an error.  zinflate doesn't actually use the bytes, so the value
 * is irrelevant.
 *
 * Returns 0 on success, non-zero on error.
 */
#ifdef MACTC5
int eofonce = 0;
#endif

int FillInBuf()
{
#ifndef MACTC5
		static int eofonce = 0;
#endif

		incnt = mfread(inbuf, INBUFSIZ, zipfd);

		if (incnt > 0) {		/* Read went okay */
				inptr = inbuf;
				--incnt;
				return 0;
		} else if (incnt == 0 && !eofonce) {	/* Special fudge case */
				eofonce++;
				incnt = 2;
				inptr = inbuf;
				return 0;
		} else {				/* Error */
				return 1;
		}
}
#endif

/**************************/
/* Function FlushOutput() */
/**************************/

int FlushOutput()
{
	/*
	 * flush contents of output buffer; return PK-type error code
	 */
	int len;

	if (outcnt) {
						len = outcnt;
			if (mfwrite(outout, len, outfd) != len)
#ifdef MINIX
				if (errno == EFBIG)
					if (write(fd, outout, len/2) != len/2  ||
						write(fd, outout+len/2, len/2) != len/2)
#endif /* MINIX */
				{
					return 50;	  /* 50:  disk full */
				}
		outpos += outcnt;
		outcnt = 0;
		outptr = outbuf;
	}
	return (0); 				/* 0:  no error */
}
